local skynet = require "skynet"
local handler = require "handler"
local util = require "util"
local reason = require "reason"
local error_code = require "error_code"
local constant = require "constant"
local utils = require "utils"
local data_access = require "data_access"
local game_def = require "game_def"
local cjson = require "cjson"
local md5 = require "md5"
local table_def = require "table_def"
local mail_def = require "mail_def"
local friendroomdata = require "friendroomdata"
local tree_handler = require "tree_handler"



local server_config = dofile(skynet.getenv("server_config"))
local table_insert = table.insert
local table_sort = table.sort
local table_remove = table.remove
local math_floor = math.floor
local math_random = math.random
local tonumber = tonumber
local tostring = tostring
local httpc = require "http.httpc"
local cocall = require "cocall"
local table_clone = table.clone


httpc.timeout = 10 * 100 --ten seconds.

local notify_money_changed = handler.notify_money_changed
local BASE_DATA_MAP = handler.BASE_DATA_MAP
local check_match_table_config = handler.check_match_table_config
local check_red_points = tree_handler.check_red_points
local add_tree_record = tree_handler.add_tree_record
local clear_tree_info = tree_handler.clear_tree_info

local hall_handler = {}

function hall_handler.PING(...)
    local curr_time = util.get_now_time()
    local rsp = {server_time = curr_time}
    send_to_gateway('hall.PONG',rsp)

    return true
end


function hall_handler.REQ_ROOMDATA_LIST(msg)
    local game_type_list = msg.game_type_list
    local roomdata = global_configs.roomdata
    local roomdata_list = {}
    for _,game_type in pairs(game_type_list) do
        for type,data in pairs(roomdata) do
            local tmp_game_type = game_def.get_game_type(type)
            if tmp_game_type == game_type then
                local tmp_num = math_random(100, 1000)
                local tmp_roomdata = {
                    table_type  = type,
                    room_name  = data.name,
                    dizhu       = data.dizhu,
                    min_limit  = data.min,
                    max_limit  = data.max,
                    cost       = data.cost,
                    play_num   = tmp_num,
                    multiple   = data.multiple,
                    img_bg     = data.img_bg,
                    eject_rate = data.eject_rate,
                    eject_time = data.eject_time,
                }

                --红包扫雷
                if game_type == table_def.GAME_TYPE_HONGBAO then
                     tmp_roomdata.room_name = tostring(data.hb_count)
                     tmp_roomdata.multiple = data.hb_times * 100                    
                end

                if data.open_game then
                    table_insert(roomdata_list,tmp_roomdata)
                end
            end
        end
    end
    table_sort(roomdata_list, function(a,b) return a.table_type < b.table_type end)
    send_to_gateway('hall.RSP_ROOMDATA_LIST',{room_data_list = roomdata_list})
    return true
end

function hall_handler.REQ_FRIEND_ROOMDATA_LIST(msg)
    local game_type_list = msg.game_type_list
    local roomdata_list = {}
    for _,game_type in pairs(game_type_list) do
        for type,data in pairs(friendroomdata) do
            if data.game_type == game_type then
                local tmp_num = math_random(100, 1000)
                local tmp_roomdata = {
                    table_type  = type,
                    room_name  = data.name,
                    dizhu       = data.dizhu,
                    min_limit  = data.min,
                    max_limit  = data.max,
                    cost       = data.cost,
                    play_num   = tmp_num,
                    multiple   = data.multiple,
                    img_bg     = data.img_bg,
                }
                if data.open_game then
                    table_insert(roomdata_list,tmp_roomdata)
                end
            end
        end
    end

    local is_white_player = false
    local ok,ret = R().hallsvr(1):call('.msg_handler','common_post_data',constant.WHITE_PLAYER_URL,{channel = player.channel},player.uid)
    if ok and ret and ret.status == 200 and ret.body then
        local body = cjson.decode(ret.body)
        is_white_player = body.code == 200 and true or false
    end

    table_sort(roomdata_list, function(a,b) return a.table_type < b.table_type end)
    send_to_gateway('hall.RSP_FRIEND_ROOMDATA_LIST',{room_data_list = roomdata_list,is_white_player = is_white_player})

    return true
end



function hall_handler.REQ_SHOP_INFO()
    local shopdata = global_configs.shop

    local tmp_list = {}
    for shop_id,data in pairs(shopdata) do
        local item_id = data.goods.item_id
        local sub_list = tmp_list[item_id]
        if not sub_list then
            sub_list = {}
            tmp_list[item_id] = sub_list
        end
        table_insert(sub_list,{
            shop_id = shop_id,
            index = data.index,
        })
    end

    for _,sub_list in pairs(tmp_list) do
        table_sort(sub_list,function(a,b) return a.index < b.index end)
    end

    local rsp_shop_item_list = {}
    for item_id,sub_list in pairs(tmp_list) do
        local shop_item_list = {}
        local goods_required
        if item_id == constant.ITEM_COIN_ID then
            goods_required = true
        end
        for _,sub_info in pairs(sub_list) do
            local shop_id = sub_info.shop_id
            local data = shopdata[shop_id]
            local price = {currency = data.price.currency,amount = data.price.amount}
            local goods
            if goods_required then
                goods = {id = item_id,count = data.goods.item_count}
            end

            local shop_info = {
                shop_id = shop_id,
                name = data.name,
                price = price,
                goods = goods,
                icon_name = data.icon_name,
                discount = (data.discount == 1),
                ios_goods_id = data.ios_goods_id
            }
            table_insert(shop_item_list,shop_info)
        end

        table_insert(rsp_shop_item_list,{
            item_id = item_id,
            shop_item_list = shop_item_list,
        })
    end

    send_to_gateway('hall.RSP_SHOP_INFO',{shop_item_list = rsp_shop_item_list})
    return true
end

local function check_channel_limit(channel,table_type)
    local channel_limit_cfg = global_configs.channel_limit or {}                                                                                                                                                                               
    local curr_time = util.get_now_time()
    local game_type = game_def.get_game_type(table_type)

    for _,limit_cfg in pairs(channel_limit_cfg) do
        local start_time = utils.get_time_by_string(limit_cfg.start_time)
        local end_time   = utils.get_time_by_string(limit_cfg.end_time)
        if (channel == limit_cfg.channel or limit_cfg.channel == "all") and 
        curr_time >= start_time and 
        curr_time <= end_time and 
        game_type == table_def.GAME_TYPE_DDZ_NORMAL then
            return true
        end
    end
    return false
end

function hall_handler.REQ_MATCH_PLAYER(msg,client_fd)
    local uid = player.uid
    local code, dest, table_gid = check_match_table_config(msg.table_type)
    dbglog("REQ_MATCH_PLAYER table_type:",msg.table_type,"code:",code)
    if code ~= 0 then
        local curr_game_type = 0
        local curr_table_type = 0
        if table_gid and table_gid > 0 then
            local ok,succ,ret_game_type,ret_table_type = R().dest(dest):call('.table_mgr','get_game_type',table_gid)
            if not ok then
                errlog(uid,'failed to get game type',table_gid,ret_game_type,ret_table_type)
                table_gid = 0
                dest = 0
            else
                curr_game_type = ret_game_type or 0
                curr_table_type = ret_table_type or 0
            end
        end
        if code == error_code.PLAYER_IS_ON_TABLE then
            if curr_table_type == msg.table_type then
                send_to_gateway('hall.RSP_MATCH_PLAYER',{})
                send_to_gateway('hall.NTF_MATCH_SUCESS',{
                    dest=dest,
                    table_gid=table_gid,
                    game_type = curr_game_type,
                })
            else
                send_to_gateway('hall.RSP_MATCH_PLAYER',{result = -11})
                send_to_gateway('hall.NTF_SELF_ONTABLE',{
                    dest=dest,
                    table_gid=table_gid,
                    game_type = curr_game_type,
                })
            end
        else
            local res = utils.getErrResult(code,dest)
            send_to_gateway('hall.RSP_MATCH_PLAYER',res)
        end
        return true
    end
    local ip_limit = global_configs.roomdata[msg.table_type].ip_limit
    local channel_limit = check_channel_limit(player.user_data.channel,msg.table_type)

    local user_data = {
        uid = uid,
        table_type = msg.table_type,
        begin_time = util.get_now_time(),

        name = player.user_data.name,
        coins = player.coins,
        sex = player.user_data.sex,
        icon = player.user_data.icon,

        match_deploy = msg.match_deploy,
        login_ip = player.user_data.last_login_ip,
        ip_limit = ip_limit,
        channel_limit = channel_limit,
    }
    
    local ok = R().newmatchsvr(1):call('.table_mgr','match_player',user_data)
    local result = 0
    if not ok then
        errlog(uid,'failed to match player')
        result = -1
    end
   
    send_to_gateway('hall.RSP_MATCH_PLAYER',{result = result})

    -- if msg.match_deploy.start_by_lucky then
    --     R().hallsvr({key=uid}):send('.msg_handler', 'start_by_lucky',uid)
    -- end
  
    return true
end


function hall_handler.REQ_SELF_TABLE(msg,client_fd)
    local uid = player.uid

    local ok,table_gid = R().exdbsvr(1):call('.tlock_mgr','get_player_table',uid)
    if not ok then
        errlog(uid,'failed to get_player_table')
        table_gid = 0
    end

    local tsvr_id = utils.extract_table_gid(table_gid)
    local dest = R().tablesvr(tsvr_id):dest()
    
    local game_type = 0
    if table_gid > 0 then
        local ok,succ,ret = R().dest(dest):call('.table_mgr','get_game_type',table_gid)
        if not ok then
            errlog(uid,'failed to get game type',table_gid,game_type)
            -- table_gid = 0
            -- dest = 0
        else
            game_type = ret or 0
        end
    else
        dest = 0
    end

    local rsp = {
        result = 0,
        dest = dest,
        table_gid = table_gid,
        game_type = game_type,
    }

    send_to_gateway('hall.RSP_SELF_TABLE',rsp)
    return true
end

function hall_handler.REQ_CHECK_ENTER(msg,client_fd)
    local uid = player.uid
    local ret = 0
    local table_type = msg.table_type
    local ok,table_gid = R().exdbsvr(1):call('.tlock_mgr','get_player_table',uid)
    if not ok then
        errlog(uid,'failed to get_player_table')
        table_gid = 0
    end

    if table_gid > 0 then
        ret = 0
    else
        ret = 1
    end

    local rsp = {
        result = 0,
        ret = ret,
        table_type = table_type,
    }

    send_to_gateway('hall.RSP_CHECK_ENTER',rsp)
    return true
end

--function hall_handler.REQ_CANCEL_MATCH_PLAYER(msg,client_fd)
--    local uid = player.uid
--    local ok,succ = R().matchsvr(1):call('.table_mgr','cancel_matching_player',uid)
--    local result = 0
--    if not ok then
--        errlog(uid,'failed to cancel')
--        result = -2
--    end
--    if not succ then
--        result = -1
--    end
--
--    send_to_gateway('hall.RSP_CANCEL_MATCH_PLAYER',{result = result})

--    return true
--end

function hall_handler.REQ_CHANGE_NAME(msg)
    local uid = player.uid
    local name = msg.name:gsub('%s','')
    if skynet.call('.textfilter','lua','is_sensitive',name) then
        return send_to_gateway('hall.RSP_CHANGE_NAME',{result = error_code.INVALID_NAME})
    end
    local user_data = player.user_data

    if user_data.has_changed_name then
        return send_to_gateway('hall.RSP_CHANGE_NAME',{result = error_code.has_changed_name})
    end

    local name_map = skynet.call('.textfilter','lua','get_utf8_length',name)

    --计算名字总长度
    local total_len = 0
    for _,wlen in pairs(name_map) do
        if wlen == 1 then
            total_len = total_len + 1
        else
            total_len = total_len + 2
        end
    end

    if total_len < 1 then
        return send_to_gateway('hall.RSP_CHANGE_NAME',{result = error_code.CHANGE_NAME_EMPTY})
    end
    
    if total_len > 10 then
        return send_to_gateway('hall.RSP_CHANGE_NAME',{result = error_code.CHANGE_NAME_TOO_LONG})
    end

    user_data.name = name
    user_data.has_changed_name = true

    send_to_gateway('hall.RSP_CHANGE_NAME',{name = name,has_changed_name = user_data.has_changed_name})

    R().friendsvr(1):send('.info_mgr','update_info',uid,{name  = name})
    return true
end

function hall_handler.REQ_CHANGE_SEX(msg)
    local uid = player.uid
    local sex = msg.sex
    if sex ~= constant.SEX_BOY and 
        sex ~= constant.SEX_GIRL and 
        sex ~= constant.SEX_SECRET then
        errlog(uid,'invalid sex',sex)
        send_to_gateway('hall.RSP_CHANGE_SEX',{result = error_code.INVALID_SEX})
        return
    end

    local user_data = player.user_data
    if user_data.sex == sex then
        return send_to_gateway('hall.RSP_CHANGE_SEX',{sex = sex,icon = user_data.icon})
    end

    
    user_data.sex = sex

    if sex == constant.SEX_BOY then
        user_data.icon = constant.ICON_BOY_DEFAULT
    elseif sex == constant.SEX_GIRL then
        user_data.icon = constant.ICON_GIRL_DEFAULT
    end

    send_to_gateway('hall.RSP_CHANGE_SEX',{sex = sex,icon = user_data.icon})

    R().friendsvr(1):send('.info_mgr','update_info',uid,{sex  = sex,icon = user_data.icon})
    return true
end

function hall_handler.REQ_CHANGE_ICON(msg)
    local uid = player.uid

    local user_data = player.user_data
    user_data.icon = msg.icon

    send_to_gateway('hall.RSP_CHANGE_ICON',{icon = user_data.icon})

    R().friendsvr(1):send('.info_mgr','update_info',uid,{sex  = user_data.sex,icon = user_data.icon})
    
    return true
end


function hall_handler.REQ_NEWBIE_AWARD(msg)
    local uid = player.uid
    if not player:can_take_newbie_award() then
        --已经领过该奖励了
        send_to_gateway('hall.RSP_NEWBIE_AWARD',{result = error_code.HAVE_TAKEN_NEWBIE_AWARD})
        return
    end

    if not player:set_newbie_award() then
        send_to_gateway('hall.RSP_NEWBIE_AWARD',{result = -2})
        return
    end

    --发奖励
    local newbie_award = global_configs.newbie_award
    if not newbie_award or not newbie_award["newbie_award"] then
        return
    end

    local award_list = {}
    for _,v in pairs(newbie_award["newbie_award"]) do
        if BASE_DATA_MAP[v.item_id] then
            table_insert(award_list,{id = v.item_id,count = v.count})
        end
    end

    local ok,succ,ret = R().basesvr{key=uid}:call('.msg_handler','add_item_list',
        uid,award_list,reason.NEWBIE_AWARD,{channel = player.channel})
    if not ok then
        errlog(uid,'failed to add_item_list',tostring_r(award_list))
        send_to_gateway('hall.RSP_NEWBIE_AWARD',{result = -3})
        return
    end

    if not succ then
        errlog(uid,'failed to call add_item_list')
        return
    end

    send_to_gateway('hall.RSP_NEWBIE_AWARD',{award_list = award_list})

    local ok,base_data = R().basesvr({key=uid}):call('.msg_handler','get_base_data',uid)
    if ok then
        notify_money_changed(uid,{
            coins = base_data.coins,
            gems = base_data.gems,
            roomcards = base_data.roomcards
        })
    end
    
    return true
end

local function check_ddz_ftable_conf(table_type,create_conf,count)
    print_r(create_conf)

    if not table_def.set_dizhu_way[create_conf.set_dizhu_way] then
        print("1111111111")
        return false
    elseif not table_def.max_dizhu_rate[create_conf.max_dizhu_rate] then
        print("22222222222222")
        return false
    elseif not table_def.count_select[create_conf.count] then
        print("23333333333333333333")
        return false
    elseif not table_def.friend_table_type_map[table_type] then
        print("244444444444444")
        return false
    end

    count = create_conf.count

    return true
end

local function check_xuezhan_ftable_conf(create_conf,count)
    count = create_conf.total_count

    if not table_def.xuezhan_count_map[create_conf.total_count] then
        return false
    elseif not table_def.xuezhan_limit_rate_map[create_conf.limit_rate] then
        return false
    elseif not table_def.xuezhan_zimo_map[create_conf.zimo_addition] then
        return false
    elseif not table_def.dianganghua_map[create_conf.dianganghua] then
        return false
    end

    return true
end

function hall_handler.REQ_BUY(msg,client_fd)
    return true
    -- local uid = player.uid
    -- local goods_id = msg.goods_id
    -- local goods_conf = global_configs.shop[goods_id]
    -- if not goods_conf then
    --     errlog(uid,'could not find goods',goods_id)
    --     return send_to_gateway('hall.RSP_BUY',{result = -1})
    -- end

    -- local base_req = {}

    -- --检查够不够扣
    -- local price = goods_conf.price

    -- local currency = price.currency
    -- if BASE_DATA_MAP[currency] then
    --     base_req.cost_item = {
    --         item_id = currency,
    --         item_num = price.amount
    --     }
    -- else
    --     errlog(uid,'invalid currency',goods_id,currency)
    --     return
    -- end

    -- local goods = goods_conf.goods
    -- if BASE_DATA_MAP[goods.item_id] then
    --     base_req.bought_item = {
    --         item_id = goods.item_id,
    --         item_num = goods.item_count
    --     }
    -- else
    --     --检查下是否是普通道具
    --     errlog(uid,'invalid goods.item_id',goods_id,goods.item_id)
    --     return
    -- end

    -- local ok,succ,ret = R().basesvr{key=uid}:call('.msg_handler','buy',uid,base_req,reason.BUY_FROM_SHOP)
    -- if not ok then
    --     errlog(uid,'failed to buy ok',goods_id)
    --     return send_to_gateway('hall.RSP_BUY',{result = -3})
    -- end

    -- if not succ then
    --     errlog(uid,'failed to buy succ',goods_id,ret)
    --     return send_to_gateway('hall.RSP_BUY',{result = ret})
    -- end
    
    -- player:billlog('basebuy',{goods_id = goods_id,item_id = goods.item_id,
    --         item_count = goods.item_count,currency = price.currency,amount = price.amount, r = reason.PAY_BY_SHOP_DETAIL})

    -- local base_data = ret
    -- notify_money_changed(uid,{
    --     coins = base_data.coins,
    --     gems = base_data.gems,
    --     roomcards = base_data.roomcards
    -- })

    -- --检查是否需要更新到桌子
    -- if goods.item_id == constant.ITEM_COIN_ID then
    --     check_update_on_table(uid,base_data)
    -- end    

    -- return send_to_gateway('hall.RSP_BUY',{
    --         goods_id = goods_id,
    --         item_id = goods.item_id,
    --         item_count = goods.item_count
    --     })
end

local function full_item_list(base_data)
    local rsp_item_list = {}
    --房卡    
    if base_data.roomcards > 0 then
        local item = {id = constant.ITEM_ROOMCARD_ID,count = base_data.roomcards}
        table_insert(rsp_item_list,item)
    end
    --记牌器(次数)
    if base_data.card_note_count > 0 then
        local item2 = {id = constant.ITEM_CNOTE_ONE_ID,count = base_data.card_note_count}
        table_insert(rsp_item_list,item2)
    end
    --记牌器(天数)
    local interval = base_data.card_note_end_time - util.get_now_time()
    local day = math.ceil(math.max(interval,0) / (24 * 60 * 60)) 
    if day > 0 then
        local item3 = {id = constant.ITEM_CNOTE_TWO_ID,count = day}
        table_insert(rsp_item_list,item3)
    end
    --超级加倍卡
    if base_data.jiabei_cards > 0 then
        local item4 = {id = constant.ITEM_JIABEICARD_ID,count = base_data.jiabei_cards}
        table_insert(rsp_item_list,item4)
    end

    return rsp_item_list
end

function hall_handler.REQ_ITEM_LIST(msg)
    -- local uid = player.uid
    -- local user_data = player.user_data
    -- local ok,base_data = R().basesvr{key=uid}:call('.msg_handler','get_base_data',uid)
    -- if not ok then
    --     errlog(uid,'failed to get_base_data info',uid)
    --     return false
    -- end

    -- send_to_gateway('hall.RSP_ITEM_LIST',{item_list = full_item_list(base_data)})
    return true
end

local function get_self_info(uid)
    local player = player
    local ok,base_data = R().basesvr({key=uid}):call('.msg_handler','get_base_data',uid)
    if not ok then
        errlog(uid,'failed to get base data',uid)
        return
    end

    local record_list = {}
    for str_game_type, info in pairs(base_data.rate_of_winning) do
        local winning_percent = math_floor(info.win_times/(info.win_times + info.fail_times)*100)
        table_insert(record_list,{game_type = tonumber(str_game_type), winning_times = info.win_times, failure_times = info.fail_times, winning_percent = winning_percent})
    end
    local personal_info = {
        uid = uid,
        name = player.user_data.name,
        sex = player.user_data.sex,
        icon = player.user_data.icon,
        coins = base_data.coins,
        gems = base_data.gems,
        roomcards = base_data.roomcards,
        record_list = record_list,
        is_self = true,
        club_play_times = base_data.club_play_times,
        vip_level = base_data.vip_level,
        icon_border = player.user_data.icon_border
    }

    return personal_info
end

local FRIEND_STATUS_DELETE = 1
local FRIEND_STATUS_ADD = 2
local FRIEND_STATUS_BEEN_REQUESTED = 3

function hall_handler.REQ_PERSONAL_INFO(msg)
    local uid = player.uid
    local target_uid = msg.uid

    if uid == target_uid then
        local personal_info = get_self_info(uid)
        send_to_gateway('hall.RSP_PERSONAL_INFO',{personal_info = personal_info})
        return true
    end

    local ok,uid_info_map = R().friendsvr(1):call('.info_mgr','get_infos',{target_uid})
    if not ok then
        errlog(uid,'failed to get_infos',target_uid)
        send_to_gateway('hall.RSP_PERSONAL_INFO',{result = -1})
        return
    end

    local info = uid_info_map[target_uid]
    if not info then
        dbglog(uid,'failed to get_infos',target_uid)
        send_to_gateway('hall.RSP_PERSONAL_INFO',{result = error_code.NO_SUCH_PLAYER})
        return
    end

    local ok,base_data = R().basesvr{key=target_uid}:call('.msg_handler','get_base_data',target_uid)
    if not ok then
        errlog(uid,'failed to get personal info',target_uid)
        return false
    end

    local is_my_friend = false
    local ok,ret = R().friendsvr(1):call('.relation','is_friend',uid,target_uid)
    if ok then
        is_my_friend = ret
    else
        errlog(uid,'failed to check is my friend',target_uid)        
    end

    local friend_status = 0
    if not is_my_friend then
        local ok,ret = R().friendsvr(1):call('.request_mgr','has_request',target_uid,uid)
        if ok then
            if ret then
                friend_status = FRIEND_STATUS_BEEN_REQUESTED
            else
                friend_status = FRIEND_STATUS_ADD
            end
        else
            errlog(uid,'failed to check requesting',target_uid)        
        end
    else
        friend_status = FRIEND_STATUS_DELETE
    end

    local record_list = {}
    for str_game_type, info in pairs(base_data.rate_of_winning) do
        local winning_percent = math_floor(info.win_times/(info.win_times + info.fail_times)*100)
        table_insert(record_list,{game_type = tonumber(str_game_type), winning_times = info.win_times, failure_times = info.fail_times, winning_percent = winning_percent})
    end
    local personal_info = {
        uid = target_uid,
        name = info.name,
        sex = info.sex,
        icon = info.icon,
        coins = base_data.coins,
        record_list = record_list,
        is_self = false,
        friend_status = friend_status,
        club_play_times = base_data.club_play_times,
        vip_level = base_data.vip_level or 0,
        icon_border = info.icon_border,
    }

    local game_type = msg.game_type
    if game_type ~= 0 then
        --表示在游戏中，增加一些道具
        local prop_list = {}
        for _,v in pairs(constant.FACE_DEF) do
            table_insert(prop_list,v)
        end
        
        personal_info.prop_price = 200
        personal_info.prop_list = prop_list
    end

    send_to_gateway('hall.RSP_PERSONAL_INFO',{
        personal_info = personal_info,
        game_type = game_type
    })

    return true
end

function hall_handler.REQ_GAME_LIST(msg)
    local uid = player.uid
    local tmp_game_info_list = {}
    local private_room_list = {}
    local quick_enter
    local channel = player.channel
    local type_list = {}
    local os_system = player.os_system
    print("REQ_GAME_LIST=================",channel)
    local game_menu = global_configs.game_list[channel] or {}
    game_menu = game_menu[os_system] or game_menu['all']
    if not game_menu then
        game_menu = global_configs.game_list['guanwang'] or {}
        game_menu = game_menu[os_system] or game_menu['all'] or {}
    end
    local game_list = game_menu.game_list or {}
    dbglog(channel,os_system,game_list)

    -- print("REQ_GAME_LIST=================",game_list)
    for k, v in pairs(game_menu.type_list or {}) do 
        type_list[k] = v
    end     
   
    for key, game_cfg in pairs(game_list) do
        if game_cfg.shown_type == 1 then --正常游戏列表
            local third_type = 0
            if game_cfg.is_third then 
                third_type = 1
            end
            table_insert(tmp_game_info_list,{
                game_type = game_cfg.game_type,
                notice_type = game_cfg.notice_type,
                position = game_cfg.position,
                name = game_cfg.name,
                status = game_cfg.status,
                category_list = table_clone(game_cfg.cretegory_list or {}, {}),
                third_type = third_type, --视讯游戏 1BG
            })
        elseif game_cfg.shown_type == 2 then --私人房
            table_insert(private_room_list,{
                game_type = game_cfg.game_type,
                notice_type = game_cfg.notice_type,
                name = game_cfg.name
            })
        elseif game_cfg.shown_type == 3 then --快速进入
            quick_enter = {
                game_type = game_cfg.game_type,
                notice_type = game_cfg.notice_type,
                name = game_cfg.name
            }
        end
    end

    --排序
    table_sort(tmp_game_info_list, function(game1, game2) return game1.position < game2.position end)
    local game_info_list = {}
    for _,v in pairs(tmp_game_info_list) do
        local t = {
            game_type = v.game_type,
            notice_type = v.notice_type,
            name = v.name,
            status = v.status,
            category_list = v.category_list,
            third_type = v.third_type, --视讯游戏 1BG
        }
        table_insert(game_info_list,t)
    end
    -- print("______game_info_list__", game_info_list)
    -- print("______222222222")
    print("___type_list__", type_list)
    send_to_gateway('hall.RSP_GAME_LIST',{
        game_info_list = game_info_list,
        private_room_list = private_room_list,
        quick_enter = quick_enter,
        type_list = type_list,
    })

    local ok,base_data = R().basesvr{key=uid}:call('.msg_handler','get_base_data',uid)
    if ok then
        notify_money_changed(uid,{
            coins = base_data.coins,
            gems = base_data.gems,
            roomcards = base_data.roomcards
        })
    end

    return true
end

function hall_handler.REQ_SYS_NOTICE_LIST(msg)
    local uid = player.uid

    local ok,notice_list = R().exdbsvr(1):call('.notice_mgr','get_notice_list',uid)
    if not ok then
        send_to_gateway('hall.RSP_SYS_NOTICE_LIST', {result = error_code.RSP_FAIL})
        return
    end

    for _, notice in pairs(notice_list) do
        notice.notice = cjson.encode(notice.notice)
    end
    send_to_gateway('hall.RSP_SYS_NOTICE_LIST', {notice_list = notice_list})
    return true
end

function hall_handler.REQ_HANDLE_NOTICE(msg)
    send_to_gateway('hall.RSP_HANDLE_NOTICE',{})
    return true
end

function hall_handler.REQ_COIN_RANK_LIST(msg)
    --[[
    local uid = player.uid

    local ok,rank_list = R().mailsvr(1):call('.coin_rank','get_curr_rank_list')
    if not ok then
        errlog(uid,'failed to get_curr_rank_list')
        send_to_gateway('hall.RSP_COIN_RANK_LIST',{result = -3001})
        return
    end

    local uid_list = {}
    for _,v in pairs(rank_list) do
        table_insert(uid_list,v.uid)
    end

    local ok,uid_info_map = R().friendsvr(1):call('.info_mgr','get_infos',uid_list)
    if not ok then
        errlog(uid,'failed to info_mgr')
        send_to_gateway('friend.RSP_COIN_RANK_LIST',{result = -3002})
        return
    end

    local rsp_rank_list = {}
    for _,v in pairs(rank_list) do
        local uid = v.uid
        local info = uid_info_map[uid] or {}
        table_insert(rsp_rank_list,{
            uid = uid,
            name = info.name,
            icon = info.icon,
            coins = v.coins
        })
    end 

    send_to_gateway('hall.RSP_COIN_RANK_LIST',{rank_list = rsp_rank_list})
    ]]
    return true
end

local function friend_rank_cmp(a,b)
    if a.incomes_coins ~= b.incomes_coins then
        return a.incomes_coins > b.incomes_coins
    end
    return a.uid > b.uid
end
function hall_handler.REQ_FRIEND_RANK_LIST(msg)
    local uid = player.uid

    local ok,uid_time_map = R().friendsvr(1):call('.relation','get_friend_list',uid)
    if not ok then
        errlog(uid,'failed to get_friend_list')
        send_to_gateway('friend.RSP_FRIEND_RANK_LIST',{result = -4001})
        return
    end

    local uid_list = {uid}
    for uid in pairs(uid_time_map) do
        table_insert(uid_list,uid)
    end

    local ok,uid_coins_map = R().friendsvr(1):call('.income_mgr','get_coins',uid_list)
    if not ok then
        errlog(uid,'failed to get_coins')
        uid_coins_map = {}
    end
    
    local ok,uid_info_map = R().friendsvr(1):call('.info_mgr','get_infos',uid_list)
    if not ok then
        errlog(uid,'failed to get_infos')
        uid_info_map = {}
    end

    local rsp_rank_list = {}
    for _,uid in pairs(uid_list) do
        local info = uid_info_map[uid] or {}
        table_insert(rsp_rank_list,{
            uid = uid,
            name = info.name,
            icon = info.icon,
            incomes_coins = uid_coins_map[uid] or 0
        })
    end 

    table_sort(rsp_rank_list,friend_rank_cmp)

    send_to_gateway('hall.RSP_FRIEND_RANK_LIST',{rank_list = rsp_rank_list})
    return true
end

function hall_handler.REQ_GET_COMPENSATION(msg)
    -- local uid = player.uid
    -- local got,ntf,curr_coins = data_access.take_compensation(uid)
    -- if got then
    --     player.base_data.coins = curr_coins
    --     notify_money_changed(uid,{coins = curr_coins})
    --     --通知桌子
    --     check_update_on_table(uid,{coins = curr_coins})
    --     skynet.fork(function()
    --         send_to_gateway('hall.RSP_GET_COMPENSATION',ntf)
    --     end)
    -- end
    return true
end

local function make_channel_version_key(channel,version)
    return channel .. '_' .. version
end
function hall_handler.REQ_GLOBAL_CONFIG(msg)
    -- local client_version = player.client_version
    -- local channel = msg.channel:lower()
    -- local version = msg.version
    -- local json_configs = {}

    -- local channel_version_cfg = global_configs.channel_version
    -- local key = make_channel_version_key(channel,client_version)
    -- local cfg = channel_version_cfg[key]
    -- if not cfg then
    --     key = make_channel_version_key(channel,'default')
    --     cfg = channel_version_cfg[key]
    -- end

    -- if not cfg then
    --     key = make_channel_version_key('default','default')
    --     cfg = channel_version_cfg[key]
    -- end

    -- if not cfg then
    --     send_to_gateway('hall.RSP_GLOBAL_CONFIG', {result = -1000})
    --     return        
    -- end

    -- local share_url_info = {
    --     title = cfg.title,
    --     des = cfg.des,
    --     target_url = cfg.targetUrl,
    --     share_img = cfg.shareImg,
    --     share_type = cfg.sharetype,
    --     share_tab = cfg.sharetab,
    --     task_share_title = cfg.task_share_title,
    --     task_share_content = cfg.task_share_content,
    --     task_share_url = cfg.task_share_url,
    -- }
    -- json_configs.share_url_info = share_url_info

    -- json_configs.announcement_url = cfg.announcement_url
    -- json_configs.kefu_url = cfg.kefu_url
    -- json_configs.agent_url = cfg.agent_url
    -- json_configs.payment_channels = cfg.payment_channels
    -- json_configs.payment_ways = cfg.payment_ways
    -- local friend_room_config = {}
    -- for table_type,tmp_friend_room in pairs(global_configs.friendroomdata) do
    --     local friend_room = {}
    --     friend_room.name = tmp_friend_room.name
    --     friend_room.is_club = tmp_friend_room.is_club
    --     friend_room.cost_type = tmp_friend_room.cost_type
    --     friend_room.cost = tmp_friend_room.cost
    --     friend_room.aa_cost = tmp_friend_room.aa_cost
    --     friend_room.max_count = tmp_friend_room.max_count
    --     friend_room.play_num = tmp_friend_room.play_num
    --     friend_room.min_dizhu = tmp_friend_room.min_dizhu
    --     friend_room.max_dizhu = tmp_friend_room.max_dizhu
    --     friend_room.min_white_dizhu = tmp_friend_room.min_white_dizhu
    --     friend_room.max_white_dizhu = tmp_friend_room.max_white_dizhu
    --     friend_room.min_ration = tmp_friend_room.min_ration
    --     friend_room.max_ration = tmp_friend_room.max_ration
    --     friend_room.comparable_bet_round = tmp_friend_room.comparable_bet_round
    --     friend_room.max_bet_round = tmp_friend_room.max_bet_round
    --     friend_room.max_look_round = tmp_friend_room.max_look_round
    --     friend_room.max_need_money = tmp_friend_room.max_need_money
    --     friend_room.ration = tmp_friend_room.ration
    --     friend_room_config[tostring(table_type)] = friend_room
    -- end
    -- json_configs.friend_room_data = friend_room_config

    -- local ret = {
    --     result = 0,
    --     channel = channel,
    --     version = version + 1,
    --     json_configs = cjson.encode(json_configs)
    -- }

    -- send_to_gateway('hall.RSP_GLOBAL_CONFIG', ret)
    
    return true
end

function hall_handler.REQ_RED_POINTS(msg)
    local player = player
    local uid = player.uid

    local module_list = {}
    --任务
    -- local red_point = false
    -- for _,task_type in pairs(constant.TASK_TYPE_DEF) do
    --     if player:check_task_process(task_type) then
    --         red_point = true
    --         break
    --     end
    -- end

    -- if red_point then
    --     table_insert(module_list,constant.MODULE_DEF.TASK)
    -- end

    --邮件
    local url  = constant.MAIL_URL --"/api/v1/server_api/get_mail_list"
    local data = cjson.encode({is_new = 1})
    local status, body = handler.common_post(url,data)
    if status == 200 and body then
        local mail_result = cjson.decode(body)
        if mail_result and mail_result.result and next(mail_result.result) then
            table_insert(module_list,constant.MODULE_DEF.MAIL)
        end
    end


    --周福利 暂时屏蔽
    -- local ok,week_award_info = R().basesvr({key=uid}):call('.msg_handler','get_week_award_info',uid)
    -- if ok and week_award_info then
    --     if week_award_info.can_exchange_award and week_award_info.can_exchange_award > 0 and week_award_info.day_count >= 7 then
    --         table_insert(module_list,constant.MODULE_DEF.WEEKAWARD)
    --     end
    -- end

    --大抽奖
    -- local ok,cur_index,code = R().mailsvr(1):call('.award_mgr','get_cur_index')
    -- if ok and cur_index then
    --     local ok,free_count = R().exdbsvr(1):call('.award_user_handler','get_free_count',uid,cur_index)
    --     if (free_count or 0) > 0 then
    --         table_insert(module_list,constant.MODULE_DEF.AWARD)
    --     end
    -- end

    ---俱乐部
    -- local ok,club_id = R().basesvr({key=uid}):call('.msg_handler','get_club_id',uid)
    -- if ok and club_id then
    --     local ok,ret = R().clubsvr(1):call('.club_mgr','check_has_apply_players',club_id,uid)
    --     if ok and ret then
    --         table_insert(module_list,constant.MODULE_DEF.CLUB)
    --     end
    -- end

    --福利中心
    local user_data = player.user_data
    local vip_award_info = user_data.vip_award_info
    local welfare_sign_info = user_data.welfare_sign_info
    local key = true
    for _,v in pairs(vip_award_info) do
        if v.status == 1 then
            table_insert(module_list,constant.MODULE_DEF.WELFARE)
            key = false
            break
        end
    end
    if key and (welfare_sign_info.sign_state == 1 or welfare_sign_info.month_state == 1) then
        table_insert(module_list,constant.MODULE_DEF.WELFARE)
    end
    dbglog(user_data.tree_info)
    pcall(check_red_points,debug.traceback,user_data.tree_info,module_list)
    dbglog("___RSP_RED_POINTS__",module_list)
    send_to_gateway('hall.RSP_RED_POINTS', {module_list = module_list})

    return true
end

function hall_handler.REQ_BIND_INVITER(msg)
    local player = player
    local uid = player.uid
    local inviter_code = msg.inviter_code
    local ok,ret = R().accountsvr({rand=true}):call('.info_mgr','bind_inviter',
        uid,inviter_code)
    if not ok then
        errlog('failed to bind_inviter',uid,inviter_code)
        send_to_gateway('hall.RSP_BIND_INVITER', {result = -10})
        return
    end

    if not ret.succ then
        --已经邀请过了
        local result = -20
        if ret.code == -1 then
            result = error_code.BIND_INVITER_FAILED_INVALID_CODE
        elseif ret.code == -2 then
            result = error_code.BIND_INVITER_FAILED_ALREADY_DONE
        end
        send_to_gateway('hall.RSP_BIND_INVITER', {result = result})
        return true
    end

    send_to_gateway('hall.RSP_BIND_INVITER', {
        inviter_code = inviter_code, agent_name = ret.agent_name,
    })

    return true
end

function hall_handler.REQ_INVITER_PANEL(msg)
    -- local player = player
    -- local uid = player.uid

    -- local ok,ret = R().accountsvr({rand=true}):call('.info_mgr','get_inviter',uid)
    -- if not ok then
    --     errlog('failed to get_inviter',uid)
    --     send_to_gateway('hall.RSP_INVITER_PANEL', {result = -10})
    --     return
    -- end

    -- if not ret.succ then
    --     send_to_gateway('hall.RSP_INVITER_PANEL', {result = -20})
    --     return true
    -- end

    -- send_to_gateway('hall.RSP_INVITER_PANEL', {
    --     inviter_code = ret.inviter_code,  
    --     agent_name = ret.agent_name
    -- })

    return true
end

function hall_handler.REQ_DESPOSIT_SAFE_BOX_INFO(msg)
    local uid = player.uid
    local ok,curr = R().basesvr({key=uid}):call('.msg_handler','get_safe_box',uid)
    if not ok then
        errlog('failed to get safe box',ok)
        return send_to_gateway('hall.RSP_DESPOSIT_SAFE_BOX_INFO', {result = error_code.RSP_FAIL})
    end
  --  dbglog("REQ_DESPOSIT_SAFE_BOX_INFO",curr)
    return send_to_gateway('hall.RSP_DESPOSIT_SAFE_BOX_INFO', {curr_safe_box = curr})
end

function hall_handler.REQ_DESPOSIT_SAFE_BOX(msg)
    local uid = player.uid
    local coins = msg.coins
    local operate = msg.operate
    local exinfo = {channel = player.channel,cur_channel = player.cur_channel}
    if operate == 1 then
        local ok,succ,ret = R().basesvr({key=uid}):call('.msg_handler','desposit_safe_box',uid,coins,reason.DESPOSIT_SAFE_BOX,exinfo)
        if ok and succ then
            -- if ret.table_gid ~= 0 then
            --     local tsvr_id = utils.extract_table_gid(table_gid)
            --     dest = R().tablesvr(tsvr_id):send('.table_mgr','update_coins_on_table',uid,table_gid,coins)
            -- end

            notify_money_changed(uid,{coins = ret.curr})
            return send_to_gateway('hall.RSP_DESPOSIT_SAFE_BOX', {
                curr_coins = ret.curr, curr_safe_box = ret.curr_safe_box,operate = operate
            })
        else
            errlog('failed to desposit safe box',ok,succ)
            return send_to_gateway('hall.RSP_DESPOSIT_SAFE_BOX', {result = error_code.RSP_FAIL})
        end
    elseif operate == 2 then
        local ok,succ,ret = R().basesvr({key=uid}):call('.msg_handler','take_out_safe_box',uid,coins,reason.TAKE_OUT_SAFE_BOX,exinfo)
        if ok and succ then
            if ret.table_gid and ret.table_gid ~= 0 then
                -- dbglog("take_out_safe_box table_gid:",ret.table_gid,ok,succ)
                local tsvr_id = utils.extract_table_gid(ret.table_gid)
                dest = R().tablesvr(tsvr_id):send('.table_mgr','update_coins_on_table',uid,ret.table_gid,coins,ret.curr_safe_box)
            end 
            notify_money_changed(uid,{coins = ret.curr})
            return send_to_gateway('hall.RSP_DESPOSIT_SAFE_BOX', {
                curr_coins = ret.curr, curr_safe_box = ret.curr_safe_box,operate = operate
            })
        else
            errlog('failed to take out safe box',ok,succ)
            return send_to_gateway('hall.RSP_DESPOSIT_SAFE_BOX', {result = error_code.RSP_FAIL})
        end
    else
        errlog('error parmas',operate)
        return send_to_gateway('hall.RSP_DESPOSIT_SAFE_BOX', {result = error_code.RSP_FAIL})
    end

end

function hall_handler.REQ_COMMON_WEB_FORWARD(msg)
    local url = msg.url
    local data = msg.data
    local status,body = handler.common_post(url,data)
    print(url,tostring_r(data),tostring_r(body))
    if status ~= 200 then
        return send_to_gateway('hall.RSP_COMMON_WEB_FORWARD', {result = error_code.RSP_FAIL,req_type = msg.req_type})
    end

    return send_to_gateway('hall.RSP_COMMON_WEB_FORWARD', {result = error_code.RSP_SUCESS,data = body,req_type = msg.req_type})
end

function hall_handler.REQ_BIND_AGENT(new_player,name)
    return
    -- if not new_player then
    --     return
    -- end

    -- local url  = "/api/v1/onebyoneagents/bind_agent"
    -- local data = cjson.encode({ ip = util.inet_ntoa(player.ip),Nickname = name})
    -- local status,body = common_post(url,data)
    -- print("REQ_BIND_AGENT==ret===",EXCHANGE_WEBSERVER_URL,status,tostring_r(body))
end

function hall_handler.REQ_COMMON_POST(url,data)
    print("REQ_COMMON_POST1111111",uid,tostring_r(data))

    local status,body = handler.common_post(url,cjson.encode(data))
    print("REQ_COMMON_POST222222222222222",status,tostring_r(body))
    if status == 200 and body then
        local result = cjson.decode(body)
        print("REQ_COMMON_POST3333333333333",tostring_r(result))
    end
end

local function send_rank_award(awar_list)
    local mail_list = {}
    for rank,v in pairs(awar_list) do
        local mail = {}
        mail.uid = v.uid
        mail.title = mail_def.BIND_PHONE_TITLE
        mail.content = string.format(mail_def.BIND_PHONE_CONTENT,math_floor(v.coins/100))
        mail.op_user = mail_def.OP_USER
        mail.mail_type = 2
        mail.coins  = 0
       
        table_insert(mail_list,mail)
    end
    
    print("send_rank_award=========",tostring_r(mail_list))
    local url = constant.ADD_MAIL_URL
    R().hallsvr(1):send('.msg_handler','common_post_data',url,{award_list = mail_list})
end


local ACCOUNT_WEBSERVER_URL = skynet.getenv("ACCOUNT_WEBSERVER_URL") or "127.0.0.1:6668"
function hall_handler.REQ_BIND_PHONE_REWARD(msg)
    local uid = player.uid

    local newbie_award = global_configs.newbie_award
    if not player:can_take_bind_phone_award() then
        --已经领过该奖励了
        return send_to_gateway('hall.RSP_BIND_PHONE_REWARD',{result = -1})
    end

    local body = cjson.encode({uid = uid})
    local status,body = handler.common_post(constant.BECOME_AGENT, body)
    -- local status, body = httpc.request('POST',ACCOUNT_WEBSERVER_URL, 
    --     "/starry/user/is_tourist",nil,nil,body)

    if status ~= 200 then
        return send_to_gateway('hall.RSP_BIND_PHONE_REWARD',{result = -2})
    end

    local result = cjson.decode(body)
    if result.code < 0 then
        return send_to_gateway('hall.RSP_BIND_PHONE_REWARD',{result = -3})
    end
    print("___REQ_BIND_PHONE_REWARD_____", result)
    if result.type == 'PHONE' then
        if not player:set_bind_phone_award() then
            return send_to_gateway('hall.RSP_BIND_PHONE_REWARD',{result = -4})
        end

        if result.union_id then
            player.user_data.phone_code = result.union_id
        end
        
        if result.register_ip then
            player.user_data.register_ip = result.register_ip
        end
        
        if result.dev_code then
            player.user_data.register_machine = result.dev_code
        end     

        --发奖励
        local newbie_award = global_configs.newbie_award
        if not newbie_award or not newbie_award["bind_phone_award"] then
            return send_to_gateway('hall.RSP_BIND_PHONE_REWARD',{coins = 0})
        end

        local add_coins = 0
        local award_list = {}
        for _,v in pairs(newbie_award["bind_phone_award"]) do
            if BASE_DATA_MAP[v.item_id] then
                table_insert(award_list,{id = v.item_id,count = v.count})
            end
            add_coins = add_coins + v.count
        end

        local ok,succ,ret = R().basesvr{key=uid}:call('.msg_handler','add_item_list',
            uid,award_list,reason.BIND_PHONE_REWARD,{phone=result.union_id,channel = player.channel})
        if not ok or not succ then
            ERR("REQ_BIND_PHONE_REWARD get coins fail")
            return send_to_gateway('hall.RSP_BIND_PHONE_REWARD',{coins = 0})
        end

        send_rank_award({{uid = uid,coins=add_coins}})
        notify_money_changed(uid,{coins = ret.coins})
        dbglog("RSP_BIND_PHONE_REWARD",uid,add_coins,ret.coins)
        return send_to_gateway('hall.RSP_BIND_PHONE_REWARD',{coins = add_coins})
    else
        return send_to_gateway('hall.RSP_BIND_PHONE_REWARD',{result = -5})
    end
end
-- 暂时屏蔽周福利
function hall_handler.REQ_SEVEN_REWARD_INFO(msg)
    -- local uid = player.uid

    -- local seven_reward = global_configs.seven_reward
    -- if not seven_reward then
         return send_to_gateway('hall.RSP_SEVEN_REWARD_INFO',{result = -1})
    -- end

    -- local ok,week_award_info = R().basesvr({key=uid}):call('.msg_handler','get_week_award_info',uid)
    -- if not ok or not week_award_info then
    --     return send_to_gateway('hall.RSP_SEVEN_REWARD_INFO',{result = -2})
    -- end

    -- local section 
    -- for num,data in pairs(seven_reward) do
    --     if week_award_info.today_coins_water >= data.coins_low then
    --         section = num
    --     end 
    -- end
    -- if not section then
    --     return send_to_gateway('hall.RSP_SEVEN_REWARD_INFO',{result = -3})
    -- end

    -- local data = {
    --     days = week_award_info.day_count,
    --     today_coins = week_award_info.today_coins_water,
    --     yestoday_coins = week_award_info.last_award,
    --     total_coins = week_award_info.total_award,
    --     can_exchange_coins = week_award_info.can_exchange_award,
    --     section_count = section,
    --     section_hight = seven_reward[section].coins_hight > 5000000 and 5000000 or seven_reward[section].coins_hight,
    --     section_rate  = seven_reward[section].back_rate * 100,
    --     section_total_count  = #seven_reward,
    --     section_update_coins = seven_reward[section].coins_hight - week_award_info.today_coins_water,
    -- }
    -- return send_to_gateway('hall.RSP_SEVEN_REWARD_INFO',data)
end

function hall_handler.REQ_SEVEN_REWARD_EXCHANGE(msg)
    -- local uid = player.uid

    -- local ok,week_award_info = R().basesvr({key=uid}):call('.msg_handler','get_week_award_info',uid)
    -- if not ok or not week_award_info then
         return send_to_gateway('hall.RSP_SEVEN_REWARD_EXCHANGE',{result = -1})
    -- end
    -- if week_award_info.day_count < 7 then
    --     return send_to_gateway('hall.RSP_SEVEN_REWARD_EXCHANGE',{ result = error_code.CANNOT_ENTER_TEMOPORARILY})
    -- end
    -- if msg.exchange_coins > week_award_info.can_exchange_award then
    --     return send_to_gateway('hall.RSP_SEVEN_REWARD_EXCHANGE',{ result = error_code.CAN_EXCHANGE_COINS_NOT_ENOUGH})
    -- end
    -- local ok,vip_level = R().basesvr{key=uid}:call('.msg_handler', 'get_vip_level',uid)
    -- if ok and vip_level then
    --     local conf = utils.getDataBykv(global_configs.vip,"level",vip_level)
    --     print("REQ_SEVEN_REWARD_EXCHANGE==========",vip_level,conf.week_award_max,msg.exchange_coins)
    --     if conf and conf.week_award_max < msg.exchange_coins then
    --         send_to_gateway('hall.RSP_SEVEN_REWARD_EXCHANGE',{result = error_code.VIP_LEVEL_LIMIT})
    --         return
    --     end
    -- end
    
    -- local ok,ret = R().basesvr({key=uid}):call('.msg_handler','exchanged_coins',uid,msg.exchange_coins,player.channel)
    -- if not ok or not ret then
    --     return send_to_gateway('hall.RSP_SEVEN_REWARD_EXCHANGE',{ result = -2})
    -- end

    -- notify_money_changed(uid,{coins = ret.coins})

    -- R().mailsvr(1):send('.opration_message_worker','send_real_horse_message',constant.BROADCAST_IDS.BIDS_WEEK_AWARD,{name = player.user_data.name,coin = msg.exchange_coins,vip_level = player.base_data.vip_level})
    
    -- return send_to_gateway('hall.RSP_SEVEN_REWARD_EXCHANGE',{days = ret.day_count,can_exchange_coins = ret.can_exchange_award})
end

function hall_handler.REQ_SEVEN_REWARD_CONFIG(msg)
    local seven_reward = global_configs.seven_reward
    if not seven_reward then
        return send_to_gateway('hall.RSP_SEVEN_REWARD_CONFIG',{result = -1})
    end

    local data = {}
    for k,v in pairs(seven_reward) do
        local t = {}
        t.coins_low  = v.coins_low
        t.coins_high = v.coins_hight > 5000000 and 5000000 or v.coins_hight
        t.back_rate  = v.back_rate * 100
        table_insert(data,t)
    end
    return send_to_gateway('hall.RSP_SEVEN_REWARD_CONFIG',{config_list = data})
end

function hall_handler.REQ_RANK_LIST(msg)
    local uid = player.uid
    local rank_type = msg.rank_type

    local ok,rsp_info = R().mailsvr(1):call('.rank_handler','get_curr_rank_list',uid,rank_type)
    if not ok or not rsp_info then
        errlog(uid,'failed to get_curr_rank_list')
        send_to_gateway('hall.RSP_RANK_LIST',{result = -3001})
        return
    end

    send_to_gateway('hall.RSP_RANK_LIST',{rank_list = rsp_info.rsp_rank_list,
        self_value = rsp_info.type_value,
        refresh_time = rsp_info.refresh_time,
        rank_type = rank_type})
    return true
end

function hall_handler.REQ_RANK_TYPE_LIST(msg)
    local ok,rsp_type_list = R().mailsvr(1):call('.rank_handler','get_rank_type')
    if not ok or not rsp_type_list then
        errlog(uid,'failed to REQ_RANK_TYPE_LIST')
        send_to_gateway('hall.RSP_RANK_TYPE_LIST',{result = -3001})
        return
    end

    send_to_gateway('hall.RSP_RANK_TYPE_LIST',{type_list = rsp_type_list})
    return true
end

function hall_handler.REQ_PLAYER_COINS(msg)
    local uid = player.uid
    local ok,curr_coins = R().basesvr({key=uid}):call('.msg_handler','get_coins',uid)
    if not ok then
        send_to_gateway('hall.RSP_PLAYER_COINS',{result = error_code.RSP_FAIL})
        return 
    end

    notify_money_changed(uid,{coins = curr_coins})
    send_to_gateway('hall.RSP_PLAYER_COINS',{coins = curr_coins})

    return true
end

local function get_vip_open_icon_border(vip_level)
    local icon_border_map = {}
    for _,data in pairs(global_configs.vip) do
        if vip_level >= data.level then
            icon_border_map[data.icon_border_url] = true
        end
    end

    return icon_border_map
end

function hall_handler.REQ_ICON_BORDER_INFO(msg)
    local uid = player.uid
    local ok,vip_level = R().basesvr{key=uid}:call('.msg_handler', 'get_vip_level',uid)
    if not ok then
        send_to_gateway('hall.RSP_ICON_BORDER_INFO',{result = -1})
        return
    end

    local ret_list = {}
    local icon_border_map = get_vip_open_icon_border(vip_level)

    print("REQ_ICON_BORDER_INFO===========",tostring_r(icon_border_map))
    for _,data in pairs(global_configs.vip) do
        local icon_border = {}
        icon_border.name = data.name
        icon_border.url = data.icon_border_url
        icon_border.open_condition = data.condition
        icon_border.open_state = icon_border_map[data.icon_border_url] or false
        icon_border.end_time = -1
        
        table_insert(ret_list,icon_border)
    end
    send_to_gateway('hall.RSP_ICON_BORDER_INFO',{icon_border_list = ret_list})

    return true
end

function hall_handler.REQ_USE_ICON_BORDER(msg)
    local url = msg.url
    local uid = player.uid
    local ok,vip_level = R().basesvr{key=uid}:call('.msg_handler', 'get_vip_level',uid)
    if not ok then
        send_to_gateway('hall.RSP_ICON_BORDER_INFO',{result = -1})
        return
    end

    local icon_border_map = get_vip_open_icon_border(vip_level)
     print("REQ_ICON_BORDER_INFO===========",tostring_r(icon_border_map))
    if not icon_border_map[url] then -- 没有开启
        send_to_gateway('hall.RSP_USE_ICON_BORDER',{result = -2})
        return 
    end

    player.user_data.icon_border = url
    send_to_gateway('hall.RSP_USE_ICON_BORDER',{url = url})

    return true
end

function hall_handler.REQ_VIP_INFO(msg)
    local vip_conf = global_configs.vip
    local uid = player.uid
    local ok,base_data = R().basesvr({key=uid}):call('.msg_handler','get_base_data',uid)
    if not ok then
        send_to_gateway('hall.RSP_VIP_INFO',{result = -2})
        return
    end
    
    local vip_level  = base_data.vip_level
    local max_vip_level = #vip_conf - 1
    local next_level = (vip_level+1 > max_vip_level) and  max_vip_level or (vip_level+1)
    local next_level_conf = utils.getDataBykv(vip_conf,"level",next_level)
    if not next_level_conf then
        return
    end
    
    local vip_exp = vip_level == max_vip_level and next_level_conf.charge_coins or base_data.person_water
    local rsp = {
        vip_level = base_data.vip_level,
        vip_level_max = max_vip_level,
        vip_exp = vip_exp,
        vip_exp_max = next_level_conf.charge_coins,
    }
    send_to_gateway('hall.RSP_VIP_INFO',rsp)

    return true
end

function hall_handler.REQ_VIP_CONF(msg)
    local vip_conf = global_configs.vip
    if not vip_conf then
        send_to_gateway('hall.RSP_VIP_CONF',{result = -1})
        return
    end

    local function get_privilege_list(data)
        local ret_list = {}
        for type,_ in pairs(data.privilege) do
            local agr
            if type == game_def.VIP_PRIVILEGE_TYPE_ONE then
                agr = data.icon_border_url
            elseif type == game_def.VIP_PRIVILEGE_TYPE_TWO then
                agr = data.battery_url
            elseif type == game_def.VIP_PRIVILEGE_TYPE_THREE then
                agr = data.week_award_max
            elseif type == game_def.VIP_PRIVILEGE_TYPE_FOUR then
                agr = data.caishen_base_rate or 0
            elseif type == game_def.VIP_PRIVILEGE_TYPE_FIVE then
                agr = data.free_num or 0
            end
            table_insert(ret_list,{privilege_type = type,arg = agr})
        end

        return ret_list
    end

    local conf_list = {}
    for _,data in pairs(vip_conf) do
        local t = {
            vip_level = data.level,
            charge_coins = data.charge_coins,
            privilege_list = get_privilege_list(data),
            video_image_url = data.video_img_url,
            video_url = data.video_url,
        }
        table_insert(conf_list,t)
    end
    send_to_gateway('hall.RSP_VIP_CONF',{vip_conf = conf_list})

    return true
end

function get_trend_info(tablesvr_id,table_gid)
    --print("======stats.table_gid=======",tablesvr_id,table_gid)
    local tsvr_id,tbid = utils.extract_table_gid(table_gid)
    --print("get_trend_info",tsvr_id,tbid)
    local ok,data = R().tablesvr(tablesvr_id):call('.table_mgr','get_trend_info',table_gid)
    --print_r(data)
    if ok then
      --  print("get_trend_info table_gid",table_gid)
        return data
    else
        return {}
    end
end

function get_gid_list(game_type)
    --dbglog("get_gid_list",game_type)
    local ok,data = R().newmatchsvr(1):call('.table_mgr','get_gid_list',game_type)
    if not ok then
        errlog(uid,'failed to trend list')
        return {}
    end
    return data
end


function hall_handler.REQ_TREND_INFO(msg)
    --dbglog("REQ_TREND_INFO game_type:",msg.game_type," table_type:",msg.table_type)
    local ret = {}
    ret.game_type = msg.game_type
    ret.table_type = msg.table_type
    -- 获取对应房间的 gid
    local ok,table_gid = R().newmatchsvr(1):call('.table_mgr','get_table_gid',msg.game_type,msg.table_type)
    if not ok or not table_gid then
        errlog(uid,'failed to REQ_TREND_INFO ')
        ret.result = -1
        send_to_gateway('hall.RSP_TREND_INFO',ret)
        return false
    end
    
    --根基对应gid 获取牌路
    local tsvr_id,tbid = utils.extract_table_gid(table_gid)
    --dbglog("REQ_TREND_INFO tbid",tbid)
    local data = get_trend_info(tsvr_id,table_gid)
    ret.info = data
    ret.result = 0

    --dbglog(ret)

    send_to_gateway('hall.RSP_TREND_INFO',ret)
    return true
end

function hall_handler.REQ_TREND_LIST(msg)
    --dbglog("REQ_TREND_LIST ",msg.game_type)
    local batch_requests = {}
    local ret = {}
    ret.info = {}
    for _,v in pairs(msg.game_type) do
        table_insert(batch_requests,{f = get_gid_list,id = #batch_requests + 1,params = {v}})
    end

    --获取gid列表
    local ok,results = cocall(5,batch_requests)
    if not ok then
        errlog('failed to cocall',tostring_r(results))
    end

    batch_requests = {}
    for _,v in pairs(results) do
        for _,gid in pairs(v) do
            table_insert(batch_requests,{f = get_trend_info,id = #batch_requests + 1,params = {utils.extract_table_gid(gid),gid}})
        end
    end

    --牌路
    ok,results = cocall(5,batch_requests)
    if not ok then
        errlog('failed to cocall',tostring_r(results))
    end

    for _,v in pairs(results) do
        table_insert(ret.info,v)
    end
    ret.result = 0
    ret.game_type = msg.game_type

    print("__REQ_TREND_LIST__ret__", ret)
    send_to_gateway('hall.RSP_TREND_LIST',ret)
    return true
end

--------------------------------------GM命令--------------------------------
function hall_handler.REQ_GM(msg)
    if not server_config.debug then
        return
    end
    local cmd_string = msg.cmd:lower()
    local user_data = player.user_data
    local command = utils.str_split(cmd_string," ")
    local cmd = command[1]
    local params = {}
    for i = 2,#command do
        table_insert(params,command[i])
    end
    print_r(params)

    local reason = reason.GM
    local uid = player.uid
    if cmd == "addcoins" then
        local exinfo = {channel = player.channel,cur_channel = player.cur_channel,
            os_system = player.os_system,
            platform = player.platform,            
        }
        local ok,succ,ret = R().basesvr({key=uid}):call('.msg_handler','add_coins',uid,tonumber(params[1]),reason,exinfo)
        notify_money_changed(uid,{coins = ret.curr})
        --notify_user_money(player)
    elseif cmd == "addgems" then
        local ok,succ,ret = R().basesvr({key=uid}):call('.msg_handler','add_gems',
        uid,tonumber(params[1]),reason)
        notify_money_changed(uid,{gems = ret.curr})
    elseif cmd == "addroomcards" then
        local ok,succ,ret = R().basesvr({key=uid}):call('.msg_handler','add_roomcards',
        uid,tonumber(params[1]),reason)
        notify_money_changed(uid,{roomcards = ret.curr})
    elseif cmd == "reduce_roomcards" then
        local ok,succ,ret = R().basesvr({key=uid}):call('.msg_handler','reduce_roomcards',
        uid,tonumber(params[1]),reason)
        notify_money_changed(uid,{roomcards = ret.curr})
    elseif cmd == "addtaskprocess" then
    elseif cmd == "testmail" then
        local attach_list1 = {}
        attach_list1[10001] = 1
        attach_list1[10002] = 2
        player:add_mail(102,10,nil,attach_list1)
    elseif cmd == "reducecoins" then
        local exinfo = {channel = player.channel,cur_channel = player.cur_channel,
            os_system = player.os_system,
            platform = player.platform,   
        }
        local ok,succ,ret = R().basesvr({key=uid}):call('.msg_handler','reduce_coins',
        uid,tonumber(params[1]),reason,exinfo)
        if ret then
            notify_money_changed(uid,{coins = ret.curr})  
        end 
    elseif cmd == 'alltaskfinish' then
        player:update_game_process(1,1,100)
        player:update_game_process(2,1,100)
        player:update_game_process(1,200000,100)
        player:update_card_type_process(1,6,3)
        player:update_share_progress(1)
    elseif cmd == 'finishtask' then
        player:update_card_type_process(1,6,10)
    elseif cmd == "notifytask" then
        send_to_gateway('daily.NTF_TASK_CHANGED',{})
    elseif cmd == 'redpoint' then
        send_to_gateway('hall.RSP_RED_POINTS',{
            module_list = {tonumber(params[1])}
        })
    elseif cmd == 'testpay' then
        send_to_gateway("hall.NTF_PAID_SUCC",{goods_id = 100})
    elseif cmd == "set_sevenaward_day" then
        --暂时屏蔽周福利
--        R().basesvr({key = uid}):send('.msg_handler','set_week_award_day_count',uid,tonumber(params[1]))
        player.user_data.last_login_time = player.user_data.last_login_time - tonumber(params[1])*24*60*60
    elseif cmd == "setweekaward" then
        --暂时屏蔽周福利
--        R().basesvr({key = uid}):send('.msg_handler','set_week_award_can_exchange_award',uid,tonumber(params[1]))
    elseif cmd == "reset_time" or cmd == "RESET_TIME" then
        dbglog("reset_time")
        local ok,succ,ret = R().basesvr(1):send('.msg_handler','reset_time',uid,tonumber(params[1]))
        R().mailsvr(1):send('.rank_handler','reset_time',uid, tonumber(params[1]))
        player.diff_time = tonumber(params[1]) - util.get_now_time() 
        dbglog(player.diff_time)
    elseif cmd == "clear_tree_info" then
        clear_tree_info(player)
    elseif cmd == "add_tree_record" then
        add_tree_record(player,tonumber(params[1]))
    else
        errlog(uid,"invalid cmd")
        return false    
    end    
    send_to_gateway('hall.RSP_GM',{result = 0})
    return true
end

function hall_handler.REQ_PUBLIC_JUMP(msg)
    local url = constant.JUMP_URL
    local status,body = handler.common_post(url,{})
    if status ~= 200 then
        return send_to_gateway('hall.RSP_PUBLIC_JUMP', {result = error_code.RSP_FAIL})
    end

    local ok,show_first_charge = R().basesvr(1):call('.msg_handler','check_player_first_charge',player.uid)
    if not ok then
        errlog('check_player_first_charge failed',uid)
        show_first_charge = false
    end
    local activity = global_configs.activity

    local data = cjson.decode(body)
    local act_jump_data = data.result["2"]
    if act_jump_data then
        for i=#act_jump_data,1,-1 do
            local act_id = act_jump_data[i].activity_id
            print("act_id",act_id)
            if act_id then
                local cnf = activity[act_id]
                if not show_first_charge and cnf and cnf.ac_type == game_def.ACTIVITY_TYPE_FIRST_CAHRGE then
                    table_remove(act_jump_data,id)
                end
            end
        end
    end

    return send_to_gateway('hall.RSP_PUBLIC_JUMP', {result = error_code.RSP_SUCESS,data = cjson.encode(data)})
end
















handler.register_module_handlers('hall',hall_handler)


